#!/bin/sh

# 根据gcc编译时的日志，过滤出其中的错误日志，并尝试帮助排除有关的问题
# 支持从管道或者是从文件中输入
function gcc-check-build-log () {
    #echo "Gen log file : try 'make 2>&1 | tee build.log'"
    local clogfile=$1
    local log_in=""
    if [ ! -f "$clogfile"  ]; then
        echo "Info : Reading from STD-IN"
        clogfile=`tmp-gen-safe-file`
        cat /dev/null > $clogfile || return
        local cnt=0
        local ret=0
        while true ;do
            read -t 1 line
            ret=$?

            if [ $ret -ne 0 ]; then
                if [ $cnt -eq 0 ]; then
                    echo "Time out"
                    return $?
                fi
                break
            fi
            echo $line >> $clogfile
            cnt=$(($cnt+1)) # 自增
        done

        #echo $clogfile
        log_in=`cat $clogfile`
        rm $clogfile
    else
        log_in=`cat $clogfile`
    fi
    local combine_flag=0
    (
    ## 遗漏符号
    (
    combine_flag=0
    echo "${log_in}" | grep "error: expected ‘;’"  && combine_flag=1
    echo "${log_in}" | grep "error: expected ';'"  && combine_flag=1
    echo "${log_in}" | grep "error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before"  && combine_flag=1
    echo "${log_in}" | grep "error: unterminated #else"  && combine_flag=1
    [ $combine_flag -ne 0 ]
    ) && echoBlueDim "遗漏符号"

    #echo "${log_in}" | grep "error: expected ';' after top level declarator"
    #echo "${log_in}" | grep "error: expected ‘;’ before"
    echo "${log_in}" | grep "error: expected unqualified-id before numeric constant"
    echo "${log_in}" | grep "error: use of undeclared identifier"
    echo "${log_in}" | grep "expected identifier or"
    echo "${log_in}" | grep "error: function definition is not allowed"

    echo "${log_in}" | grep "error: a function-definition is not allowed here before"
    echo "${log_in}" | grep "error: expected declaration or statement"
    echo "${log_in}" | grep "error: ‘struct "| grep "has no member named"
    echo "${log_in}" | grep "is used uninitialized"
    echo "${log_in}" | grep "warning: suggest parentheses around assignment"

    ## 类型错误
    echo "${log_in}" | grep "error: value of type"
    echo "${log_in}" | grep "error: initializer element is not computable at load time"  && echoBlueDim "赋值时存在错误，可能与类型不匹配有关系"

    ## 定义出错
    echo "${log_in}" | grep "error: duplicate case value"
    echo "${log_in}" | grep "error:" | grep "was not declared"
    echo "${log_in}" | grep "error: cast from pointer to integer of different size"
    echo "${log_in}" | (grep -A 2 "implicit declaration of function")

    ## 定义但是未使用
    (
    combine_flag=0
    echo "${log_in}" | grep "set but not used" | grep "warning: variable" && combine_flag=1
    echo "${log_in}" | grep "warning: unused variable" && combine_flag=1
    echo "${log_in}" | grep "defined but not used" && combine_flag=1
    [ $combine_flag -ne 0 ]
    ) && echoBlueDim "存在未使用的成员"

    ## 函数域返回值的问题
    echo "${log_in}" | grep "error: could not convert"
    echo "${log_in}" | grep "error: return-statement with a value"

    ## 指针和结构体访问的问题
    echo "${log_in}" | grep "maybe you meant to use"
    echo "${log_in}" | grep "error: base operand of ‘->’ has non-pointer type"

    echo "${log_in}" | grep "error: binding reference of type"
    echo "${log_in}" | grep "error: invalid storage class for function"
    echo "${log_in}" | grep "error: expected unqualified-id before"

    ## 顺序
    echo "${log_in}" | grep "sorry, unimplemented: non-trivial designated initializers not supported" && echoBlueDim "C++结构体初始化时，必须按照定义的顺序进行初始化，不能够跳过其中内容而初始化其他选项"
    echo "${log_in}" | grep "error: jump to label" && echoBlueDim "goto 与 label 之间，不能有 变量定义。"

    # -Werror
    echo "${log_in}" | grep "all warnings being treated as errors"
    echo "${log_in}" | grep "error" -n  | grep "forbidden warning"

    # ninja
    echo "${log_in}" | grep "ninja: error: unknown target"

    ## 链接时有关
    (
    echo "${log_in}" | grep "ld:" | awk '{$1="";print}' | grep "undefined reference to"
    ) && echoBlueDim "缺少函数实现，检查是否为：库链接选项，函数名错误"
    )
    #expected ‘;’
}

## 快速创建c程序
function cdemo () {
    local filename="$1"
	if [ -z "$filename" ]; then
		return
	fi
    (
cat <<EOF
#include <stdio.h>

int main(int argc, char * argv[])
{
    return 0;
}
EOF
    ) > $filename && echo "Created : [$filename]"
}

function cppdemo () {
    local filename="$1"
	if [ -z "$filename" ]; then
		return
	fi
    (
cat <<EOF
#include <iostream>
using std::ios;
using std::cout;
using std::endl;

#ifdef __cplusplus
extern "C"{
#endif

// C code...

#ifdef __cplusplus
}
#endif

int main(int argc, char * argv[])
{
    return 0;
}
EOF
    ) > $filename && echo "Created : [$filename]"
}
